import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Random;
import java.util.Vector;

public class XPercentModel extends CoAuthorModel {
  double x_;

  public XPercentModel(String initFile, double x, int nc) throws IOException{
    super();
//    super.initialize(initFile);
    
    degs_ = super.parseGraph(initFile);
    x_ = x;
    numCon_ = nc;

    process();
  }
  
  public void process() {
    Collections.shuffle(degs_);
    
    cumDeg_ = 0;
    maxDeg_ = -1;
    numNodes_ = degs_.size();
    for (int i = 0; i < degs_.size(); ++i) {
      cumDeg_ += degs_.get(i);
      
      maxDeg_ = Math.max(maxDeg_, degs_.get(i));
    }
  }
  
  public void growGraph(int nodesToAdd, int numConnection) {
    Random randGen = new Random();
    
    for (int i = 0; i < nodesToAdd; ++i) {
      Vector<Integer> potNeighbors = new Vector<Integer>();
      Vector<Integer> newNeighbors = new Vector<Integer>();
      
      double xp = ((double)numNodes_ * x_) / 100.0;
      for (int j = 0; j < (int)xp; ++j) {
        int p = randGen.nextInt(cumDeg_);

        int nbr = -1;
        for (int k = 0; k < degs_.size(); ++k) {
          p -= degs_.get(k);
          
          if (p <= 0) {
            nbr = k;
            break;
          }
        }
        
        potNeighbors.add(nbr);
      }

      for (int j = 0; j < numConnection; ++j) {
        int p = randGen.nextInt(potNeighbors.size());
        int nbr = potNeighbors.get(p);
        
        if (newNeighbors.contains(nbr)) {
          j--;
          continue;
        }
        
        newNeighbors.add(nbr);
      }
      
      if (newNeighbors.size() != numConnection)
        System.err.println("newNeighbors.size() != numConnection");
      
      degs_.add(numConnection);
      for (int  j = 0; j < newNeighbors.size(); ++j) {
        int ni = newNeighbors.get(j);
        
        Integer d = degs_.get(ni);
        degs_.set(ni, d + 1);
      }
      
      cumDeg_ += (numConnection * 2);
      numNodes_++;
    }
  }
  
  public void run(String sourceDir, int total) throws IOException {
    int date = 19950501;
    int steps_left = 48;
    
    while (date <= 20110101) {
      int to_add = (total - numNodes_) / steps_left;
      steps_left--;
      
      growGraph(to_add, numCon_);
      
      String dirName = sourceDir + "/" + getXPercentFileName(x_, numCon_);
      File dir = new File(dirName);
      dir.mkdir();

      super.dumpGraph(dirName, date);
      
      int d = date % 100;
      int m = (date / 100) % 100;
      int y = (date / 10000);
      
      m += 4;
      if (m > 12) {
        m %= 12;
        y++;
      }
      
      date = y * 10000 + m * 100 + d;
    }
    
    /*if (numNodes_ != total) {
      int nRem = (total - numNodes_);
      System.out.println("Remaining nodes: " + nRem);
      
      growGraph(each_step, NUM_CONNECTION);
      dumpGraph(sourceDir + "/model" + NUM_CONNECTION, 20110101);
      
    }*/
    
    if (numNodes_ != total) System.err.println("numNodes_ != total");
  }  
}
